简单介绍JNI和NDK

JNI:Java Native Interface,java本地接口,可以使Java与本地其他语言进行交互,如C语言,C++。
NDK:Native Development Kit是Android的一个开发工具包,快速开C与C++的动态库,并自动将so文件和应用一起打包成APK

简单快速方法

先在setting下载好ndk,cmake,lldb,然后新建项目

选择native c++然后next,输入项目名称,一路next到finish。


打开main文件夹下的cpp文件,可以看到已经写好的CMakeLists.txt和native-lib.cpp,native-lib.cpp文件,它是提供对外接口的,之后我们调用时就是通过一个java类调用这个c++文件中的接口的。

打开main文件夹下的build.gradle,填写一些配置

修改成:

build一下就生成了.so文件,在app——>build——>intermediates——>cmake下生成对应的.so库

使用此种方法.so文件声明调用都在MainActivity中,而且对外接口只有一个native-lib.cpp,不能使用多个.cpp文件实现功能。
解决办法:第一种:参考完整版写一个Java文件用javah生成.h文件,完成c代码复制到之前的native-lib.cpp中,然后rebuild;第二种将得到的接口文件(.h文件)在cpp文件夹下新建一个.cpp文件将接口文件的代码复制进去,并在CMakeLists.txt中添加新.cpp文件的源文件地址,rebuild即可。

完整版

个人觉得这个版本复杂很多但是我们可以更完整的了解建立so库的全部过程,对于后面逆向的学习有更好的理解

新建一个空项目,在Project Structure里面配置好NDK,不知道为什么在gradle3.5不能下载应用ndk之后自动配置,每一次要手动配置。


检查是否配置好在gradle这个文件夹下查看local.properties文件里面是否函数有ndk的地址。

新建一个Testjni.java

1
2
3
4
5
6
7
8
public class MyJni {

static {
System.loadLibrary("testjni");
}

public native static String getString();
}

点击build–>make project,生成.class文件

找到classes文件夹,一般在E:\Android\TestJNI\app\build\intermediates\javac\debug下,使用javah来生成.h文件,命令为

-jni com_example_testjni_testjni ```,生成com_example_testjni_testjni.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

在src/main/下创建jni目录将上述.h文件复制进去,并创建.c文件,并把下面代码复制进去
```JAVA
#include <jni.h>
#include "com_example_testjni_testjni.h"
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jstring JNICALL com_example_testjni_testjni_getString
(JNIEnv *env, jclass jz){

return (*env)->NewStringUTF(env,"this is the first time for me to use jni");

}
#ifdef __cplusplus
}
#endif

再创建Android.mk和Application.mk文件(个人觉得这种太麻烦了,Cmake简单明了)
Android.mk是一个向Android NDK构建系统描述NDK项目的GNU makefile片段。我的理解是链接文件,告诉ndk操作的一些信息
Android.mk

1
2
3
4
5
6
7
8
9
10
#定义模块当前路径(必须定义在文件开头,只需定义一次)
LOCAL_ PATH := $(call my-dir)
#清空当前环境变量 (LOCAL_PATH除外)
include $(CLEAR_VARS )
#当前模块名(这里会生成libhello-jni.so),模块名唯一,且不能包含空格
LOCAL_MODULE := testjni
#当前模块包含的源代码文件
LOCAL_ SRC_ FILES := test.c
#表示当前模块将被编译成一个共享库
include $(BUILD_ SHARED_LIBRARY)

Application.mk

1
APP_ABI := armeabi armeabi-v7a x86 // 生成so文件的平台 ,设置为all, 代表所有平台

切换到main目录下 执行ndk-build 生成so文件

将我们生成的so文件复制到 app下的libs文件夹下,并配置build.gradle 文件

在MainActivity中调用

别问我图在哪儿,上传不了。